package ha.web.server.database;


import java.util.HashMap;
import java.util.List;
import java.util.Map;

import ha.web.server.exceptions.LoginException;
import ha.web.server.exceptions.RegisterException;

public class UserManager {
	
	protected DBConnector con = DBConnector.getInstance();
	private Map<Integer,UserId> currentUserLogin = new HashMap<Integer,UserId>();
	private static UserManager singleton = null;
	
	private final int MIN_LENGTH_PASS = 6;
	private final int MAX_LENGTH_PASS = 12;
	
	
	
	
	public static UserManager getInstance() {
		if(singleton==null)
			singleton = new UserManager();
		return singleton;
	}
	
	private UserManager () {}
	
	public void createNewUserAtDB(String name, String pass, String rePass,String nickName, boolean admin) throws RegisterException, LoginException{
		validateRegister(name,nickName,pass,rePass);
		con.addUserAtDB(name,nickName, pass, admin);
	}
	
	
	public UserId login(String name, String pass) throws RegisterException, LoginException  {
		for(UserId user : currentUserLogin.values()) {
			if(user.getName().equals(name) && user.getPass().equals(pass)) {
				return user;
			}
		}
		UserId newLoginUser = validateLogin(name,pass);
		currentUserLogin.put(newLoginUser.getUserID(), newLoginUser);
		return newLoginUser;
	}
	
	private void validateRegister(String name, String nickName, String pass,String rePass) throws RegisterException, LoginException {
		//check repeat pass
		if(!pass.equals(rePass))
			throwException(true,"Password validation does not match to the password ");
		//check length of pass
		if(pass.length()<MIN_LENGTH_PASS || pass.length() > MAX_LENGTH_PASS)
			throwException(true,"The password must be between 6-12 characters");
		//check pass contain number and letter
		validatePass(pass,true);
		//check name contains only letters
		validateName(name,"User name",true);
		validateName(nickName,"Nick name",true);
		
	}

	private UserId validateLogin(String name, String pass) throws RegisterException, LoginException {
		//check name contains only letters
		validateName(name,"user name",false);
		//check pass contain number and letter
		validatePass(pass,false);
		//check unique name and nick name
		UserId toRet = DBConnector.getInstance().validateLogin(name, pass);
		if(toRet == null)
			throwException(false,"Problam at user name or pass");
		return toRet;
			
	}

	private void validatePass(String str, boolean isRegister) throws RegisterException, LoginException  {
		char[] charArray = str.toCharArray();
		boolean asLetter = false;
		boolean asDigit = false;
		for(char ch : charArray) {
			if(Character.isLetter(ch))
				asLetter = true;
			else if(Character.isDigit(ch))
				asDigit = true;
			else
				throwException(isRegister,"password must contain letters or digit only");
		}
		if(!asLetter)
			throwException(isRegister,"password must contain at list one letters");
		if(!asDigit)
			throwException(isRegister,"password must contain at list one digit");
	}

	private void validateName(String str,String valName, boolean isRegister) throws LoginException, RegisterException{
		char[] charArray = str.toCharArray();
		for(char ch : charArray) {
			if(!Character.isLetter(ch))
				throwException(isRegister,valName+" must contain only letters");
		}
	}
	
	private void throwException ( boolean isRegister,String msg) throws RegisterException, LoginException {
		if(isRegister)
			throw new RegisterException("Register Error: "+msg);
		else
			throw new LoginException("Login Error: "+msg);
	}

	public String getUserStatistics(String nickName, int userId) throws LoginException {
		if(!currentUserLogin.containsKey(userId))
			throw new LoginException("User are not login to the server");
		UserId tmp  = currentUserLogin.get(userId);
		if(tmp.getUserID()!=userId)
			throw new LoginException("Plese login again");
		return con.GetUserStatistics(tmp);
	}

	public boolean isUserAtDB(String nickName, int userId) throws LoginException {
		if(!currentUserLogin.containsKey(userId))
			throw new LoginException("User are not login to the server");
		UserId tmp  = currentUserLogin.get(userId);
		if(tmp.getUserID()!=userId)
			throw new LoginException("Plese login again");
		return true;
	}

	public void updateStatistics(List<UserStatistics> statistics) {
		UserStatistics sta;
		UserId tmp;
		sta = statistics.get(0);
		tmp = currentUserLogin.get(sta.getUserId());
		con.updateUserStatistics(tmp, sta.isWon(), sta.isResigned(),
				sta.getBigestJump(), sta.getNumberOfMove());
		sta = statistics.get(1);
		tmp = currentUserLogin.get(sta.getUserId());
		con.updateUserStatistics(tmp, sta.isWon(), sta.isResigned(),
				sta.getBigestJump(), sta.getNumberOfMove());
		
	}
	
	
}
